package com.demo2.todo.controller;

import com.demo2.todo.exception.ResourceNotFoundException;
import com.demo2.todo.model.dto.TodoRequest;
import com.demo2.todo.model.dto.TodoResponse;
import com.demo2.todo.model.entity.Todo;
import com.demo2.todo.model.entity.User;
import com.demo2.todo.model.enums.ReviewStatus;
import com.demo2.todo.repository.TodoRepository;
import com.demo2.todo.service.TodoImportExportService;
import com.demo2.todo.service.TodoService;
import com.demo2.todo.service.UserService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author evi
 */
@RestController
@RequestMapping("/todos")
@RequiredArgsConstructor
public class TodoController {
    private final TodoService todoService;
    private final UserService userService;
    private final TodoRepository todoRepository;
    private final TodoImportExportService todoImportExportService;

    @GetMapping
    public ResponseEntity<List<TodoResponse>> getAllTodos() {
        return ResponseEntity.ok(todoService.getAllTodos(userService.getCurrentUserEntity()));
    }

    @GetMapping("/{id}")
    public ResponseEntity<List<TodoResponse>> getTodoById(@PathVariable Long id) {
        return ResponseEntity.ok(todoService.getTodosByUserId(id));
    }

    @GetMapping("/admin/all")
    @PreAuthorize("hasRole('ADMIN')") // 需要ADMIN角色
    public ResponseEntity<List<TodoResponse>> getAllTodosForAdmin() {
        return ResponseEntity.ok(todoService.getAllTodosForAdmin());
    }

    @PostMapping
    public ResponseEntity<TodoResponse> createTodo(@Valid @RequestBody TodoRequest request) {
        return ResponseEntity.ok(todoService.createTodo(request, userService.getCurrentUserEntity()));
    }

    @PutMapping("/{id}")
    public ResponseEntity<TodoResponse> updateTodo(
            @PathVariable Long id,
            @Valid @RequestBody TodoRequest request
    ) {
        return ResponseEntity.ok(todoService.updateTodo(id, request, userService.getCurrentUserEntity()));
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteTodo(@PathVariable Long id) {
        todoService.deleteTodo(id, userService.getCurrentUserEntity());
        return ResponseEntity.noContent().build();
    }

    // 新增：切换待办事项状态
    @PatchMapping("/{id}/status")
    public ResponseEntity<TodoResponse> toggleTodoStatus(
            @PathVariable Long id,
            @RequestBody Map<String, String> statusRequest) {
        User currentUser = userService.getCurrentUserEntity();
        TodoResponse updatedTodo = todoService.toggleStatus(id, statusRequest.get("status"), currentUser);
        return ResponseEntity.ok(updatedTodo);
    }

    // 新增：生成分享链接
    @PostMapping("/{id}/share")
    public ResponseEntity<Map<String, String>> createShareLink(
            @PathVariable Long id) {
        User currentUser = userService.getCurrentUserEntity();
        String shareToken = todoService.createShareToken(id, currentUser);

        Map<String, String> response = new HashMap<>();
        response.put("shareToken", shareToken);
        return ResponseEntity.ok(response);
    }

    // 新增：通过分享链接获取待办事项（无需登录）
    @GetMapping("/shared/{token}")
    public ResponseEntity<TodoResponse> getSharedTodo(@PathVariable String token) {
        TodoResponse todo = todoService.getSharedTodoByToken(token);
        return ResponseEntity.ok(todo);
    }

    // 补充批量导入导出接口
    @GetMapping("/export")
    public ResponseEntity<ByteArrayResource> exportTodos() {
        User currentUser = userService.getCurrentUserEntity();
        List<Todo> todos = todoRepository.findByUserOrderByCreatedAtDesc(currentUser);
        ByteArrayResource resource = todoImportExportService.exportTodos(todos);

        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"todos.xlsx\"")
                .body(resource);
    }

    @PostMapping("/import")
    public ResponseEntity<List<TodoResponse>> importTodos(@RequestParam("file") MultipartFile file) {
        User currentUser = userService.getCurrentUserEntity();
        List<Todo> importedTodos = todoImportExportService.importTodos(file, currentUser);
        List<TodoResponse> responses = importedTodos.stream()
                .map(this::mapToDto)
                .collect(Collectors.toList());
        return ResponseEntity.ok(responses);
    }

    // 管理员审核待办事项
    @PatchMapping("/admin/review/{id}")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<TodoResponse> reviewTodo(
            @PathVariable Long id,
            @RequestParam ReviewStatus status,
            @RequestParam(required = false) String comment) {
        Todo todo = todoRepository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("待办事项不存在"));
        todo.setReviewStatus(status);
        todoRepository.save(todo);
        return ResponseEntity.ok(mapToDto(todo));
    }

    // 管理员获取所有待审核事项
    @GetMapping("/admin/pending")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<List<TodoResponse>> getPendingReviewTodos() {
        List<Todo> todos = todoRepository.findByReviewStatus(ReviewStatus.pending);
        return ResponseEntity.ok(todos.stream()
                .map(this::mapToDto)
                .collect(Collectors.toList()));
    }

    // 在TodoController中添加
    @GetMapping("/public")
    public ResponseEntity<List<TodoResponse>> getPublicTodos() {
        List<TodoResponse> publicTodos = todoService.getPublicTodos();
        return ResponseEntity.ok(publicTodos);
    }

    /**
     * Todo实体转换为响应DTO
     */
    private TodoResponse mapToDto(Todo todo) {
        TodoResponse response = new TodoResponse();
        response.setId(todo.getId());
        response.setTitle(todo.getTitle());
        response.setContent(todo.getContent());
        response.setStatus(todo.getStatus());
        response.setCreatedAt(todo.getCreatedAt());
        response.setDeadline(todo.getDeadline());
        return response;
    }

}